﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Data.Linq;
using System.Text;
using Microsoft.SqlServer.Types;
using System.Data.SqlTypes;
using NUnit.Framework;

namespace StorageUnitTests.Geospatial
{
    using Storage;
    using Storage.EntityModels;

    #region SetUp class

    /// <summary>
    /// This class contains the set up method that is executed once 
    /// before any of the fixtures contained in this namespace.
    /// </summary>
    [SetUpFixture]
    public class SetUpClass
    {
        /// <summary>
        /// This method is runned before all other tests. 
        /// It is used to get the TripLoaDbEntities.
        /// </summary>
        [SetUp]
        public void SetUpMethod()
        {
            GeospatialSupportTests.db = StorageManager.Instance.Entities;
        }
    }

    #endregion

    /// <summary>
    /// This class contains all tests related to Geospatial data.
    /// </summary>
    [TestFixture]
    public class GeospatialSupportTests
    {
        public static TripLoaDataContext db;

        #region TestSearchTrips

        [Test]
        public void TestSearchTrips()
        {
            Assert.AreEqual(TestsHelper.CreateTripForSearch(), 
                StorageManager.Instance.Entities.SearchTrips(89, 35, 0, 41, 5, 0).First(), "Viaggio non trovato");
        }

        [Test]
        public void TestSearchTripsWithTolerance()
        {
            Assert.AreEqual(TestsHelper.CreateTripForSearch(),
                StorageManager.Instance.Entities.SearchTrips(89, 35.1f, 1000, 41, 5, 0).First(), "Viaggio non trovato");
        }

        #endregion

        #region TestSearchTripsByOrigin

        [Test]
        public void TestSearchTripsByOrigin()
        {
            Assert.AreEqual(TestsHelper.CreateTripForSearch(),
                StorageManager.Instance.Entities.SearchTrips(89, 35, 0, 0, 0, 0).First(), "Viaggio non trovato");
        }

        #endregion

        #region TestSearchTripsByDestination

        [Test]
        public void TestSearchTripsByDestination()
        {
            Assert.AreEqual(TestsHelper.CreateTripForSearch(),
                StorageManager.Instance.Entities.SearchTrips(0, 0, 0, 41, 5, 0).First(), "Viaggio non trovato");
        }

        #endregion

        #region TestPlaceInsert

        [Test]
        public void TestPlaceInsertAndSelect()
        {
            Place p = new Place()
            {
                MapPoint = SqlGeography.Point(12.3567, 5.1983763, 4326)
            };

            db.Places.InsertOnSubmit(p);
            db.SubmitChanges();

            var q = from pl in db.Places
                    select p;

            Place res = q.First();

            Assert.AreEqual("POINT (12.3567 5.1983763)", res.MapPoint.ToString());
        }

        #endregion

        #region TestGetPlaceByLatLong

        [Test]
        public void TestGetPlaceByLatLong()
        {
            Place p = new Place()
            {
                MapPoint = SqlGeography.Point(12.3567, 5.1983763, 4326)
            };

            db.Places.InsertOnSubmit(p);
            db.SubmitChanges();

            Place res = StorageManager.Instance.GetPlaceByLatLong(12.3567, 5.1983763);

            Assert.AreEqual("POINT (12.3567 5.1983763)", res.MapPoint.ToString());
        }

        #endregion

        /// <summary>
        /// 
        /// </summary>
        [Test]
        public void TestDrivingInfoMapPointGet()
        {
            Stage s = TestsHelper.CreateStage();
            db.Stages.InsertOnSubmit(s);
            
            DrivingInfo d = new DrivingInfo
            {
                StageId = s.Id,
                MapPoint = s.Origin.MapPoint
            };
            db.DrivingInfos.InsertOnSubmit(d);
            db.SubmitChanges();

            var q = from info in db.DrivingInfos
                    where info.StageId == s.Id
                    select info;

            //Assert.AreEqual(d.MapPoint, q.First().MapPoint);
            Assert.AreEqual(d.MapPoint.ToString(), q.First().MapPoint.ToString());
        }

        /// <summary>
        /// 
        /// </summary>
        [Test]
        public void TestDrivingInfoMapPointSet()
        {
            //var info = db.DrivingInfo_selectByPk(11, 0).First();

            //db.DrivingInfo_updateAsString(11, 0, "70", "80", "newinfo");

            //var info2 = db.DrivingInfo_selectByPk(11, 0).First();

            //Assert.AreEqual("POINT (70 80)", info2.MapPoint.ToString());
        }

        /// <summary>
        /// 
        /// </summary>
        [Test]
        public void TestPlaceMapPointGet()
        {
            //var place = db.Place_selectByPk(27).First();
            //Assert.AreEqual("POINT (15 20)", place.MapPoint.ToString());
        }

        /// <summary>
        /// 
        /// </summary>
        [Test]
        public void TestPlaceGeoPointSet()
        {
            //var place = db.Place_selectByPk(27).First();

            //db.Place_updateAsString(place.Id, place.City, place.Province, place.Location, place.Address, 
            //    place.State, place.Category, "15", "20", "BEL POSTO", null, "www.romina.it");

            //var place2 = db.Place_selectByPk(27).First();

            //Assert.AreEqual("POINT (15 20)", place2.MapPoint.ToString());
            
        }

        /// <summary>
        /// 
        /// </summary>
        [Test]
        public void TestStagePathGet()
        {
            //var stg = db.Stage_selectByPk(11).First();
            //Assert.AreEqual("MULTIPOINT ((6 7 8), (8 9 10))", stg.Path.ToString());
        }

        /// <summary>
        /// 
        /// </summary>
        [Test]
        public void TestStagePathSet() // Il test viene superato anche con piu punti nel path
        {
            //var stg = db.Stage_selectByPk(11).First();

            //db.Stage_updateAsString(stg.Id, stg.TripId, stg.Ordinal, stg.OriginPlaceId, stg.DestinationPlaceId, 
            //    stg.UserId, stg.VehicleId, stg.ReservedSeats, stg.BusySeats, stg.EstimatedTime,
            //    stg.EstimatedBudget, "(6 7 8), (8 9 10)", null, "BELLA GITA");
            
            //var stg1 = db.Stage_selectByPk(11).First();

            //Assert.AreEqual("MULTIPOINT ((6 7 8), (8 9 10))", stg1.Path.ToString());
        }

        /// <summary>
        /// 
        /// </summary>
        [Test]
        public void TestStageViaPointsGet()
        {
            //var stg = db.Stage_selectByPk(11).First();
            //Assert.AreEqual("MULTIPOINT ((6 7 8), (5 7 8), (8 9 10))", stg.ViaPoints.ToString());
        }

        /// <summary>
        /// 
        /// </summary>
        [Test]
        public void TestStageViaPointsSet() // Il test viene superato anche con piu punti nel path
        {
            //var stg = db.Stage_selectByPk(11).First();

            //db.Stage_updateAsString(stg.Id, stg.TripId, stg.Ordinal, stg.OriginPlaceId, stg.DestinationPlaceId,
            //    stg.UserId, stg.VehicleId, stg.ReservedSeats, stg.BusySeats, stg.EstimatedTime,
            //    stg.EstimatedBudget, "(6 7 8), (8 9 10)", "(6 7 8), (5 7 8), (8 9 10)", "BELLA GITA");

            //var stg1 = db.Stage_selectByPk(11).First();

            //Assert.AreEqual("MULTIPOINT ((6 7 8), (5 7 8), (8 9 10))", stg1.ViaPoints.ToString());
        }
        
        [Test]
        public void TestPlaceSelect()
        {
            //var q = db.Place_selectByPk(5);
            //Assert.AreEqual("POINT (66 6)", q.First().MapPoint.ToString());
        }

        [Test]
        public void TestPlaceDelete()
        {
            //int count = Storage.StorageManager.Instance.Entities.Places.Count();
            //var q1 = db.Place_delete(7);
            //var q2 = db.Place_delete(8);
            //var q3 = db.Place_delete(9);
            //int count1 = Storage.StorageManager.Instance.Entities.Places.Count();

            //Assert.AreEqual(count1, count - 3);
        }

        #region SetUp

        /// <summary>
        /// Executed before every test.
        /// </summary>
        [SetUp]
        public void SetUpMethod()
        {
            TestsHelper.CleanUpDB(db);
        }

        #endregion

    }
}
